package com.cloudfun.campusshare.service.impl;

import com.cloudfun.campusshare.common.constant.Code;
import com.cloudfun.campusshare.common.exception.BusinessException;
import com.cloudfun.campusshare.common.model.vo.DeviceSchoolExportVO;
import com.cloudfun.campusshare.common.model.vo.SchoolAddVO;
import com.cloudfun.campusshare.common.model.vo.SchoolDetailVO;
import com.cloudfun.campusshare.common.model.vo.SchoolListVO;
import com.cloudfun.campusshare.common.response.PageResult;
import com.cloudfun.campusshare.entity.DeviceEntity;
import com.cloudfun.campusshare.entity.SchoolEntity;
import com.cloudfun.campusshare.repo.DeviceEntityRepo;
import com.cloudfun.campusshare.repo.SchoolEntityRepository;
import com.cloudfun.campusshare.service.SchoolService;
import com.cloudfun.campusshare.util.BeanCopyUtil;
import com.cloudfun.campusshare.util.QueryUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author : zhangyongjie
 * @createTime : 2020/3/18 15:13
 * @version : 1.0
 * @description : 学校信息service
 */
@Service
public class SchoolServiceImpl implements SchoolService {
    @Resource
    private SchoolEntityRepository schoolEntityRepository;
    @Resource
    private DeviceEntityRepo deviceEntityRepo;
    @Autowired
    private EntityManager entityManager;

    @Override
    public void addSchool(SchoolAddVO schoolAddVO) {
        if(StringUtils.isBlank(schoolAddVO.getId())){
            SchoolEntity entity = BeanCopyUtil.copy(schoolAddVO, SchoolEntity.class);
            schoolEntityRepository.save(entity);
        }else{
            Optional<SchoolEntity> school = schoolEntityRepository.findById(schoolAddVO.getId());
            if(!school.isPresent()){
                throw new BusinessException(Code.ERROR,"找不到对应的学校");
            }
            SchoolEntity schoolEntity = school.get();
            schoolEntity.setCity(schoolAddVO.getCity());
            schoolEntity.setProvince(schoolAddVO.getProvince());
            schoolEntity.setCompositeScore(schoolAddVO.getCompositeScore());
            schoolEntity.setEducateLevel(schoolAddVO.getEducateLevel());
            schoolEntity.setMaleRatio(schoolAddVO.getMaleRatio());
            schoolEntity.setName(schoolAddVO.getName());
            schoolEntity.setRank(schoolAddVO.getRank());
            schoolEntity.setRunningAttribute(schoolAddVO.getRunningAttribute());
            schoolEntity.setStudentNumber(schoolAddVO.getStudentNumber());
            schoolEntity.setType(schoolAddVO.getType());
            schoolEntityRepository.save(schoolEntity);
        }

    }

    @Override
    public PageResult getSchoolList(Pageable pageable, String keyword) {
        Page<SchoolEntity> schoolPage = schoolEntityRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (!StringUtils.isBlank(keyword)) {
                predicates.add(criteriaBuilder.like(root.get("name"), "%" + keyword + "%"));
            }
            Predicate[] preArr = new Predicate[predicates.size()];
            return criteriaBuilder.and(predicates.toArray(preArr));
        }, pageable);
        List<SchoolListVO> result = schoolPage.getContent().stream().map(x -> {
            SchoolListVO copy = BeanCopyUtil.copy(x, SchoolListVO.class);
            List<DeviceEntity> deviceEntityList = deviceEntityRepo.findBySchoolId(x.getId());
            copy.setDeviceCount((long) deviceEntityList.size());
            return copy;
        }).collect(Collectors.toList());
        PageResult pg = new PageResult(schoolPage.getTotalElements(),result);
        return pg;
    }

    @Override
    public void deleteSchool(String schoolId) {
        List<DeviceEntity> deviceList = deviceEntityRepo.findBySchoolId(schoolId);
        if (!CollectionUtils.isEmpty(deviceList)){
            throw new BusinessException(Code.ERROR,"该学校存在关联设备，无法删除");
        }

        schoolEntityRepository.deleteById(schoolId);
    }

    @Override
    public SchoolDetailVO getSchoolDetail(String schoolId) {
        return BeanCopyUtil.copy(schoolEntityRepository.findById(schoolId).orElseThrow(()->new BusinessException(Code.ERROR,"没有找到对应id的学校信息")),SchoolDetailVO.class);
    }

    @Override
    public PageResult getSchoolDeviceList(Pageable pageable, String schoolId) {
        StringBuilder sb = new StringBuilder("select d.device_name,u.enterprise_name,d.product_type,d.address," +
                "d.last_interaction_time,d.id from device d LEFT JOIN user u on d.user_id=u.id where d.school_id = :schoolId");
        sb.append(" limit :start,:end");
        Query query = entityManager.createNativeQuery(sb.toString());
        query.setParameter("schoolId",schoolId);
        query.setParameter("start",pageable.getPageNumber()*pageable.getPageSize());
        query.setParameter("end",pageable.getPageSize());
        Query countQuery = entityManager.createNativeQuery("select d.device_name,u.enterprise_name,d.product_type,d.address," +
                "d.last_interaction_time,d.id from device d LEFT JOIN user u on d.user_id=u.id where d.school_id = :schoolId");
        countQuery.setParameter("schoolId",schoolId);
        Long count = Objects.isNull(QueryUtil.getSingleResult(countQuery))?0L:(Long)QueryUtil.getSingleResult(countQuery);
        List<Object[]> list = query.getResultList();
        List<DeviceSchoolExportVO> result = list.stream().map(x -> {
            return DeviceSchoolExportVO.builder().deviceName((String) x[0]).username((String) x[1])
                    .productType((String) x[2]).address((String) x[3]).lastInteractionTime((String) x[4]).imei((String) x[5]).build();
        }).collect(Collectors.toList());
        return new PageResult(count,result);
    }


    @Override
    public List<DeviceSchoolExportVO> getSchoolExportList(String schoolId) {
        StringBuilder sb = new StringBuilder("select d.device_name,u.enterprise_name,d.product_type,d.address," +
                "d.last_interaction_time,d.id from device d LEFT JOIN user u on d.user_id=u.id where d.school_id = :schoolId");
        Query query = entityManager.createNativeQuery(sb.toString());
        query.setParameter("schoolId",schoolId);
        List<Object[]> list = query.getResultList();
        List<DeviceSchoolExportVO> result = list.stream().map(x -> {
            return DeviceSchoolExportVO.builder().deviceName((String) x[0]).username((String) x[1])
                    .productType((String) x[2]).address((String) x[3]).lastInteractionTime((String) x[4]).imei((String) x[5]).build();
        }).collect(Collectors.toList());
        return result;
    }


}
